using System;
using System.Collections.Generic;
using System.ServiceProcess;
using System.Text;
using System.Xml.Serialization;

namespace Universe.Farm.Builtin
{
    [Serializable]
    public class MsSqlDescription
    {
        public List<SqlInstance> Instances = new List<SqlInstance>();

        public override string ToString()
        {
            StringBuilder ret = new StringBuilder();
            foreach (SqlInstance instance in Instances)
            {
                if (ret.Length > 0)
                    ret.Append("; ");

                ret.Append(instance.IsDefault ? "(default)" : instance.Name);
                if (instance.Ver != null)
                    ret.Append(" ").Append(instance.Ver);

                ret.Append(" ").Append(instance.Status);
            }

            return ret.ToString();
        }

        [Serializable]
        public class SqlInstance
        {
            [XmlAttribute]
            public string Name;
            
            [XmlIgnore]
            public Version Ver;

            [XmlAttribute("OK")]
            public bool IsOK;

            [XmlAttribute("Description")]
            public string Description;

            [XmlAttribute("Status")]
            public ServiceControllerStatus Status;
            private string _level;

            public string VersionAsString
            {
                get { return Ver.ToString();  }
                set { Ver = new Version(value);}
            }

            public SqlInstance()
            {
            }


            public SqlInstance(string name)
            {
                Name = name;
            }

            public bool IsDefault
            {
                get { return string.IsNullOrEmpty(Name); }
            }

            public string FullLocalName
            {
                get { return IsDefault ? "(local)" : ("(local)" + "\\" + Name); }
            }

            public string ServiceKey
            {
                get { return GetServiceKey(Name); }
            }

            [XmlAttribute("Level")]
            public string Level
            {
                get { return _level; }
                set { _level = value; }
            }

            public VersionLevel ForecastLevel
            {
                get
                {
                    Version ver = Ver;
                    if (ver == null)
                        return VersionLevel.Unknown;

                    int m = ver.Major, b = ver.Build;
                    if (m == 8)
                    {
                        if (b < 194)
                            return VersionLevel.SQL2000 | VersionLevel.CTP;

                        else if (b < 384)
                            return VersionLevel.SQL2000 | VersionLevel.RTM;

                        else if (b < 532)
                            return VersionLevel.SQL2000 | VersionLevel.SP1;

                        else if (b < 760)
                            return VersionLevel.SQL2000 | VersionLevel.SP2;

                        else if (b < 2039)
                            return VersionLevel.SQL2000 | VersionLevel.SP3;

                        else 
                            return VersionLevel.SQL2000 | VersionLevel.SP4;
                    }

                    else if (m == 9)
                    {
                        if (b < 1399)
                            return VersionLevel.SQL2005 | VersionLevel.CTP;

                        else if (b < 2047)
                            return VersionLevel.SQL2005 | VersionLevel.RTM;

                        else if (b < 3042)
                            return VersionLevel.SQL2005 | VersionLevel.SP1;

                        else 
                            return VersionLevel.SQL2005 | VersionLevel.SP2;
                    }

                    else if (m == 10)
                    {
                        if (b < 1600)
                            return VersionLevel.SQL2008 | VersionLevel.CTP;

                        else 
                            return VersionLevel.SQL2008 | VersionLevel.RTM;
                    }

                    else 
                        return VersionLevel.Unknown;
                }
            }
        }

        [Flags]
        public enum VersionLevel
        {
            Unknown = 0,

            SQL2000 = 1024,
            SQL2005 = 2048,
            SQL2008 = 4096,
            
            CTP = 1,
            RTM = 2,
            SP1 = 4,
            SP2 = 8,
            SP3 = 16,
            SP4 = 32,


            SQL2000CTP = SQL2000 | CTP,
            SQL2000RTM = SQL2000 | RTM,
            SQL2000SP1 = SQL2000 | SP1,
            SQL2000SP2 = SQL2000 | SP2,
            SQL2000SP3 = SQL2000 | SP3,
            SQL2000SP4 = SQL2000 | SP4,

            SQL2005CTP = SQL2005 | CTP,
            SQL2005RTM = SQL2005 | RTM,
            SQL2005SP1 = SQL2005 | SP1,
            SQL2005SP2 = SQL2005 | SP2,

            SQL2008CTP = SQL2008 | CTP,
            SQL2008RTM = SQL2008 | RTM

        }

        public static string GetServiceKey(string instanceName)
        {
            return string.IsNullOrEmpty(instanceName) ? "MSSQLSERVER" : "MSSQL$" + instanceName; 
        }
    }
}
